#include "HedgehogBlobb.h"
#include "GameApp.h"

//-------------------------------------------------------------------------------------
HedgehogBlobb::HedgehogBlobb(void)
	: Actor("enemies/hedgehogblobb.xml")
{
	mTypes.push_front(OBJECT_ENEMY);
	mTypes.push_front(OBJECT_HEDGEHOGBLOBB);
	mPause = 0.0f;
	mLoad = 0;

	readFromXML("enemies/hedgehogblobb.xml");
}
HedgehogBlobb::HedgehogBlobb(boost::shared_ptr<SettingsManager> sm)
	: Actor(sm)
{
	mTypes.push_front(OBJECT_ENEMY);
	mTypes.push_front(OBJECT_HEDGEHOGBLOBB);
	mPause = 0.0f;
	mLoad = 0;

	readFromXML(sm);
}
//-------------------------------------------------------------------------------------
HedgehogBlobb::~HedgehogBlobb(void)
{
}
//-------------------------------------------------------------------------------------
void HedgehogBlobb::readFromXML(std::string id)
{
	//load XML file into SettingsManager
	boost::shared_ptr<SettingsManager> sm(new SettingsManager(id));

	//load stats
	boost::shared_ptr<Stats> stats(new Stats(sm));
	mStats = stats;

	mMinPause = (float)atof(sm->getSetting("HedgehogData/minPause").c_str());
	mLoadTime = atoi(sm->getSetting("HedgehogData/loadTime").c_str());
}
//-------------------------------------------------------------------------------------
void HedgehogBlobb::readFromXML(boost::shared_ptr<SettingsManager> sm)
{
	//load stats
	boost::shared_ptr<Stats> stats(new Stats(sm));
	mStats = stats;

	mMinPause = (float)atof(sm->getSetting("HedgehogData/minPause").c_str());
	mLoadTime = atoi(sm->getSetting("HedgehogData/loadTime").c_str());
}
//-------------------------------------------------------------------------------------
void HedgehogBlobb::update(const unsigned long elapsedTime)
{
	const float attackRange = 2.0f;

	updateStun(elapsedTime);
	updateAirStatus(elapsedTime);

	if (mStates[MOVE_AIR])
	{
		if (getLocalVelocity().y() > 0.0f)
			mMoveState = MOVE_JUMPUP;
		else mMoveState = MOVE_JUMPDOWN;

	}

	mPause -= elapsedTime / 1000.0f;
	if (mPause < 0.0f) mPause = 0.0f;

	if (elapsedTime > mLoad) mLoad = 0;
	else mLoad -= elapsedTime;

	PlayerPtr player = gpApp->mpGameLogic->getCharacter();
	btVector3 targetPos = player->getBody()->getWorldTransform().getOrigin();
	btVector3 myPos = mpBody->getWorldTransform().getOrigin();

	btScalar range = myPos.distance(targetPos);

	mpBody->activate();

	switch (mMoveState)
	{
	case MOVE_IDLE:
		if (range > moveRange) break;
		if (mLoad == 0)
		{
			// attack player with eagleshot if he is in range
			if (range < attackRange)
			{
				mMoveState = MOVE_ATTACK;
				gpApp->mpGameLogic->createParticleSystem(Ogre::String("EagleShot"), 400, cvt(mpBody->getWorldTransform().getOrigin()));
				mPause = 0.3;
				break;
			}
		}
		if (mPause == 0.0f)
		{
			btMatrix3x3 &rot = mpBody->getWorldTransform().getBasis();
			btVector3 dir = targetPos - myPos;

			// Jump in player's direction or if need time to load in the other direction
			btVector3 localDir = rot.inverse() * dir;
			if (mLoad > 0)
			{
				if (localDir.x() <= 0.0f)
				{
					setLocalVelocity(btVector3(5.0f, 15.0f, 0.0f));
					if (mStates[MOVE_LEFT])
					{
						lookRight();
					}
				}
				else
				{
					setLocalVelocity(btVector3(-5.0f, 15.0f, 0.0f));
					if (!mStates[MOVE_LEFT])
					{
						lookLeft();
					}
				}
			}
			else if (localDir.x() > 0.0f)
			{
				setLocalVelocity(btVector3(5.0f, 15.0f, 0.0f));
				if (mStates[MOVE_LEFT])
				{
					lookRight();
				}
			}
			else
			{
				setLocalVelocity(btVector3(-5.0f, 15.0f, 0.0f));
				if (!mStates[MOVE_LEFT])
				{
					lookLeft();
				}
			}

			mPause = mMinPause + 2.0f * rand()/(float)RAND_MAX;
			break;
		}
	case MOVE_JUMPUP:
		mpAnimator->playAnimation(ANIM_FULL, Ogre::String("Blob_Jump_Up"));
		if (mStates[MOVE_AIR]) mMoveState = MOVE_IDLE;
		break;
	case MOVE_JUMPDOWN:
		mpAnimator->playAnimation(ANIM_FULL, Ogre::String("Blob_Jump_Down"));
		if (mStates[MOVE_AIR]) mMoveState = MOVE_IDLE;
		break;
	case MOVE_ATTACK:
		if (mPause == 0.0f)
		{
			if (attackRange > range) player->recieveDmg(mpBody->getWorldTransform().getOrigin(), getStats()->getStat(STAT_DAMAGE));
			mMoveState = MOVE_IDLE;
			mLoad = mLoadTime;
			mPause = mMinPause * 0.5f + 1.0f * rand()/(float)RAND_MAX;
		}
		break;
	default:
		return;
	}
}
//------------------------------------------------------------------------------------
void HedgehogBlobb::collision(BaseObjectPtr obj, btVector3 &point)
{
	switch (obj->getType())
	{
		case OBJECT_PLAYER:
			{
				ActorPtr actor = boost::static_pointer_cast<Actor>(obj);
				float damage = getStats()->getStat(STAT_DAMAGE);
				if(mStates[MOVE_AIR])
				{
					actor->recieveDmg(mpBody->getWorldTransform().getOrigin(), damage);
				}
				break;
			}
		default: return;
	}
}
//-------------------------------------------------------------------------------------
void HedgehogBlobb::scalePower(const char power)
{
	switch (power)
	{
	case 0:
		break;
	case 1:
		mMinPause = 0.5f;
		mLoadTime = 1400;
		mHealthCap *= 1.5f;
		mHealth = mHealthCap;
		getStats()->setStat(STAT_DAMAGE, getStats()->getStat(STAT_DAMAGE) * 2.0f);
		break;
	case 2:
		mMinPause = 0.3f;
		mLoadTime = 1000;
		mHealthCap *= 2.0f;
		mHealth = mHealthCap;
		getStats()->setStat(STAT_DAMAGE, getStats()->getStat(STAT_DAMAGE) * 3.5f);
		break;
	default:
		break;
	}
}